package cn.xingzhe.monster.user.domain.service;

import cn.hutool.core.util.RandomUtil;
import cn.xingzhe.monster.user.domain.model.CaptchaModel;
import cn.xingzhe.monster.user.domain.enums.CaptchaTypeEnum;
import cn.xingzhe.monster.user.domain.repository.CaptchaRepository;
import cn.xingzhe.monster.user.domain.exception.InvalidCaptchaException;

/**
 * 验证码领域服务
 * 处理验证码相关的领域业务逻辑
 *
 * @author System
 * @version 1.0.0
 * @since 2024-01-01
 */
public class CaptchaDomainService {

    private final CaptchaRepository captchaRepository;
    private final int captchaLength;
    private final int expireMinutes;

    public CaptchaDomainService(CaptchaRepository captchaRepository, int captchaLength, int expireMinutes) {
        this.captchaRepository = captchaRepository;
        this.captchaLength = captchaLength;
        this.expireMinutes = expireMinutes;
    }

    /**
     * 生成验证码
     *
     * @param key  键（手机号或邮箱）
     * @param type 验证码类型
     * @return 验证码领域模型（已保存）
     */
    public CaptchaModel generateCaptcha(String key, CaptchaTypeEnum type) {
        // 删除旧的验证码
        captchaRepository.deleteByKeyAndType(key, type);

        // 生成随机数字验证码
        String code = RandomUtil.randomNumbers(captchaLength);

        // 创建验证码领域模型
        CaptchaModel captchaModel = CaptchaModel.create(key, code, type, expireMinutes);
        
        // 保存验证码
        return captchaRepository.save(captchaModel);
    }

    /**
     * 验证验证码
     *
     * @param key       键（手机号或邮箱）
     * @param inputCode 输入的验证码
     * @param type      验证码类型
     * @return 是否验证通过
     */
    public boolean verifyCaptcha(String key, String inputCode, CaptchaTypeEnum type) {
        CaptchaModel captcha = captchaRepository.findByKeyAndType(key, type)
                .orElseThrow(() -> InvalidCaptchaException.incorrect());

        if (captcha.isExpired()) {
            captchaRepository.deleteByKeyAndType(key, type);
            throw InvalidCaptchaException.expired();
        }

        boolean isValid = captcha.validate(inputCode);

        // 验证成功后删除验证码
        if (isValid) {
            captchaRepository.deleteByKeyAndType(key, type);
        }

        return isValid;
    }

    /**
     * 检查验证码是否有效
     *
     * @param key  键（手机号或邮箱）
     * @param type 验证码类型
     * @return 是否有效
     */
    public boolean isCaptchaValid(String key, CaptchaTypeEnum type) {
        return captchaRepository.findByKeyAndType(key, type)
                .map(CaptchaModel::canUse)
                .orElse(false);
    }
}

